package org.wheel.plugins.toolkit.sql.capability;

import org.wheel.plugins.toolkit.sql.core.AbstractWrapper;
import org.wheel.plugins.toolkit.sql.core.SqlSegment;
import org.wheel.plugins.toolkit.sql.core.Wrapper;
import org.wheel.plugins.toolkit.sql.function.FunctionBuilder;
import org.wheel.plugins.toolkit.sql.helper.ColumnRef;
import org.wheel.plugins.toolkit.sql.helper.SFunction;

import java.util.Arrays;
import java.util.List;

/* ========== 1. select 能力 ========== */
public interface LambdaSelect<W extends LambdaSelect<W,T>, T> {

    /* ---------- 字段 ---------- */
    default W select(SFunction<T,?>... cols){
        return select(Arrays.stream(cols)
                .map(c -> ColumnRef.of(c, (AbstractWrapper<?, ?>) this))
                .toArray(SqlSegment[]::new));
    }
    /* 底层原子 */
    W select(SqlSegment... segments);

    /* ---------- 函数 ---------- */
    default W select(FunctionBuilder fn){
        return select(fn.toSegment());   // 把 FunctionBuilder 转成 SqlSegment
    }

    /* ---------- collection / association ---------- */
    default <A,R> W selectCollection(SFunction<A, List<R>> fn, Class<R> itemClass){
        return selectCollection(fn, itemClass, null);
    }
    <A,R> W selectCollection(SFunction<A, List<R>> fn, Class<R> itemClass, String tableAlias);
//    {
//        String field = LambdaUtils.getFieldName(fn);
//        if(StrUtil.isBlank(tableAlias)) {
//            tableAlias = AliasRegistry.getInstance().resolveAlias(itemClass);
//        }
//        return select(SelectBuilder.collection(tableAlias, field, itemClass));
//    }

    <R> W selectAssociation(SFunction<T, R> assocFn, Class<R> assocClass, String tableAlias);

    default  <R> W selectAssociation(SFunction<T, R> assocFn, Class<R> assocClass){
        return selectAssociation(assocFn, assocClass, null);
    }
//    {
//        String field = LambdaUtils.getFieldName(assocFn);
//        if(StrUtil.isBlank(tableAlias)) {
//            tableAlias = AliasRegistry.getInstance().resolveAlias(assocClass);
//        }
//        return select(SelectBuilder.collection(tableAlias, field, assocClass));
//    }
}
